home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / console / svgatext.3 / svgatext / SVGATextMode-1.3 / XFREE / common_hw / I2061Acal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-29  |  4.4 KB  |  140 lines

  1. /* $XConsortium: I2061Acal.c,v 1.1 95/01/26 15:25:49 kaleb Exp $ */
  2. /* Based on the number 9 Inc code */
  3. /* Copyright (c) 1992, Number Nine Computer Corp.  All Rights Reserved.
  4.  *
  5.  * Permission to use, copy, modify, distribute, and sell this software and its
  6.  * documentation for any purpose is hereby granted without fee, provided that
  7.  * the above copyright notice appear in all copies and that both that
  8.  * copyright notice and this permission notice appear in supporting
  9.  * documentation, and that the name of Number Nine Computer Corp not be used 
  10.  * in advertising or publicity pertaining to distribution of the software 
  11.  * without specific, written prior permission.  Number Nine Computer Corp 
  12.  * makes no representations about the suitability of this software for any 
  13.  * purpose.  It is provided "as is" without express or implied warranty.
  14.  *
  15.  * NUMBER NINE COMPUTER CORP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
  16.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, 
  17.  * IN NO EVENT SHALL NUMBER NINE COMPUTER CORP BE LIABLE FOR ANY SPECIAL, 
  18.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 
  19.  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
  20.  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
  21.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  */
  24. /* Header: /home/src/xfree86/mit/server/ddx/xf86/common_hw/RCS/ICD2061Acalc.c,v 1.1 1993/03/22 00:25:21 jon Exp jon
  25.  */
  26.  
  27. #include "compiler.h"
  28. #include "ICD2061A.h"
  29.  
  30. #undef  MIN
  31. #define MIN(a, b)               (((a) < (b)) ? (a) : (b))
  32. #undef  MAX
  33. #define MAX(a, b)               (((a) > (b)) ? (a) : (b))
  34.  
  35. #define MAX_NUMERATOR           130
  36. #define MAX_DENOMINATOR         MIN(129, CRYSTAL_FREQUENCY / 400000)
  37. #define MIN_DENOMINATOR         MAX(3, CRYSTAL_FREQUENCY / 2000000)
  38.  
  39. int clock_m;
  40. int clock_n;
  41. int clock_p;
  42.  
  43. /* Index register frequency ranges for ICD2061A chip */
  44. static long     vclk_range[16] = {
  45.                 0, /* should be MIN_VCO_FREQUENCY, but that causes problems. */
  46.          51000000,
  47.          53200000,
  48.          58500000,
  49.          60700000,
  50.          64400000,
  51.          66800000,
  52.          73500000,
  53.          75600000,
  54.          80900000,
  55.          83200000,
  56.          91500000,
  57.         100000000,
  58.         120000000,
  59.         MAX_POST_SCALE,
  60.                 0,
  61.         };
  62.  
  63. long
  64. ICD2061ACalcClock(frequency, select)
  65. register long   frequency;               /* in Hz */
  66. int select;
  67. {
  68.   register long         index;
  69.   long                  temp;
  70.   long                  min_m, min_n, min_diff;
  71.   long                  diff;
  72.  
  73.   min_diff = 0xFFFFFFF;
  74.   min_n = 1;
  75.   min_m = 1;
  76.  
  77.   /* Calculate 18 bit clock value */
  78.   clock_p = 0;
  79.   if (frequency < MIN_VCO_FREQUENCY)
  80.     clock_p = 1;
  81.   if (frequency < MIN_VCO_FREQUENCY / 2)
  82.     clock_p = 2;
  83.   if (frequency < MIN_VCO_FREQUENCY / 4)
  84.     clock_p = 3;
  85.   frequency <<= clock_p;
  86.   for (clock_n = 4; clock_n <= MAX_NUMERATOR; clock_n++)
  87.     {
  88.       index = CRYSTAL_FREQUENCY / (frequency / clock_n);
  89.       if (index > MAX_DENOMINATOR)
  90.         index = MAX_DENOMINATOR;
  91.       if (index < MIN_DENOMINATOR)
  92.         index = MIN_DENOMINATOR;
  93.       for (clock_m = index - 3; clock_m < index + 4; clock_m++)
  94.         if (clock_m >= MIN_DENOMINATOR && clock_m <= MAX_DENOMINATOR)
  95.           {
  96.             diff = (CRYSTAL_FREQUENCY / clock_m) * clock_n - frequency;
  97.             if (diff < 0)
  98.               diff = -diff;
  99.             if (min_m * ICD2061AGCD(clock_m, clock_n) / ICD2061AGCD(min_m, min_n) == clock_m &&
  100.               min_n * ICD2061AGCD(clock_m, clock_n) / ICD2061AGCD(min_m, min_n) == clock_n)
  101.             if (diff > min_diff)
  102.               diff = min_diff;
  103.             if (diff <= min_diff)
  104.               {
  105.                 min_diff = diff;
  106.                 min_m = clock_m;
  107.                 min_n = clock_n;
  108.               }
  109.           }
  110.     }
  111.   clock_m = min_m;
  112.   clock_n = min_n;
  113.  
  114.   /* Calculate the index */
  115.   temp = (((CRYSTAL_FREQUENCY / 2) * clock_n) / clock_m) << 1;
  116.   for (index = 0; vclk_range[index + 1] < temp && index < 15; index++)
  117.     ;
  118.  
  119.   /* Pack the clock value for the frequency snthesizer */
  120.   temp = (((long)clock_n - 3) << 11) + ((clock_m - 2) << 1)
  121.                 + (clock_p << 8) + (index << 18) + ((long)select << 22);
  122.  
  123.   return temp;
  124. }
  125.  
  126.  
  127. /* Number theoretic function - GCD (Greatest Common Divisor) */
  128. long
  129. ICD2061AGCD(a, b)
  130. register long a, b;
  131. {
  132.   register long c = a % b;
  133.   while (c)
  134.     a = b, b = c, c = a % b;
  135.   return b;
  136. }
  137.  
  138.  
  139.  
  140.